package asynq_instance

import (
	"encoding/json"

	"gitee.com/huangxinbo/xcas/internal/app/base"
	"gitee.com/huangxinbo/xcas/internal/asynq_handle_routes"
	"gitee.com/huangxinbo/xcas/internal/config"
	"github.com/hibiken/asynq"
	"github.com/redis/go-redis/v9"
	"go.uber.org/zap"
)

func NewAsnyqServer(redisConfig *config.RedisConfig, asynqConfig *config.AsynqConfig) *asynq.Server {
	return asynq.NewServerFromRedisClient(
		redis.NewClient(&redis.Options{
			Addr:     redisConfig.Addr,
			Username: redisConfig.Username,
			Password: redisConfig.Password,
			DB:       asynqConfig.DB,
		}),
		asynq.Config{
			Concurrency: asynqConfig.Concurrency, // 并发 worker 数量
			Queues: map[string]int{
				"critical": asynqConfig.Critical,
				"default":  asynqConfig.Default,
				"low":      asynqConfig.Low,
			},
		},
	)
}

func NewAsnyqClient(redisConfig *config.RedisConfig, asynqConfig *config.AsynqConfig) *asynq.Client {
	return asynq.NewClientFromRedisClient(redis.NewClient(&redis.Options{
		Addr:     redisConfig.Addr,
		Username: redisConfig.Username,
		Password: redisConfig.Password,
		DB:       asynqConfig.DB,
	}))
}

func NewAsynqTask(base *base.Base, route asynq_handle_routes.AsynqHandleRoute, payload any) *asynq.Task {
	RouteCommonPayload := asynq_handle_routes.RouteCommonPayload{
		Language:   base.I18n.Locale,
		XRequestId: base.Logger.XRequestId,
	}

	// Create a struct that embeds both the common payload and the specific payload
	type CombinedPayload struct {
		Common asynq_handle_routes.RouteCommonPayload `json:"common"`
		Data   any                                    `json:"data"`
	}

	combinedPayload := CombinedPayload{
		Common: RouteCommonPayload,
		Data:   payload,
	}

	payloadBytes, err := json.Marshal(combinedPayload)
	if err != nil {
		base.Logger.Error("NewAsynqTask json.Marshal error", zap.Error(err))
		return nil
	}
	task := asynq.NewTask(string(route), payloadBytes, asynq.MaxRetry(5))
	return task
}
